package com.xbdun.comweb.bmp.util;

import java.net.InetAddress;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;
import com.xbdun.common.api.Client;
import com.xbdun.common.exceptions.BizException;
import com.xbdun.comweb.bmp.constants.SessionConstant;
import com.xbdun.comweb.bmp.session.CurrentUserInfo;
import com.xbdun.comweb.bmp.session.IUserAuth;
import com.xbdun.comweb.bmp.session.UserSessionData;

/**
 * 用户基本信息工具
 * @author zhanggt
 */
public abstract class UserInfoUtil {
	private static final Logger log = LoggerFactory.getLogger(UserInfoUtil.class);
	private static String IP = ""; //当前IP地址
	private static String MACHINE = "";//当前本机名称machine
	static{
		InetAddress addr=null;  
        try{  
            addr=InetAddress.getLocalHost();  
            IP=addr.getHostAddress().toString();//获得本机IP　　  
            MACHINE=addr.getHostName().toString();//获得本机名称  
        }catch(Exception e){  
            e.printStackTrace();  
        }finally{addr = null;}
	}
	/**判断用户是否存在*/
	public static final boolean existUserInfo(HttpServletRequest currentRequest){
		if(null==currentRequest)return false;
		String sessionId=(String)currentRequest.getSession().getAttribute(SessionConstant.SESSION_KEY);
        return StringUtils.isNotBlank(sessionId);
	}
	/**
	* @Title: getClient
	* @Description: 获取当前的Client
	* @throws BizException    错误
	* @return Client    返回类型
	 */
	public static final Client getClient(HttpServletRequest currentRequest,CurrentUserInfo userInfoExcption)throws BizException{
		Client client = new Client();
		
		//当前客户端
		client.setOrgCode(userInfoExcption.getOrgCode());		//用户所在机构编号
		client.setOrgName(userInfoExcption.getOrgName());		//用户所在机构名称
		client.setRoleId(userInfoExcption.getRoleId());			//用户角色
		client.setUserCode(userInfoExcption.getUserCode());		//用户编号
		client.setUserId(userInfoExcption.getUserId());			//用户ID
		client.setUserName(userInfoExcption.getUserName());		//用户名真实
		client.setPlatCode(userInfoExcption.getPlatCode()); 	//当前用户登录的平台
		
		//设置当前机器的IP/机器名称
		client.setMachine(MACHINE);
		client.setIp(IP);
		return client;
	}
	/**
	* @Title: getClient
	* @Description 根据当前请求获取用户登录信息
	* @param currentRequest
	* @return Client    返回类型
	 */
	public static final Client getClient(HttpServletRequest currentRequest){
		CurrentUserInfo userInfoExcption = getCurrentUserInfoExcption(currentRequest);
		return getClient(currentRequest,userInfoExcption);
	}
	/**
	 * 获取当前的HttpRequest
	 * @return HttpServletRequest
	 */
	public final static HttpServletRequest getCurrentRequest(){
	    //return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
	    return ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
	}
	
	/**获取当前用户，不出错**/
	public final static CurrentUserInfo  getCurrentUserInfo(HttpServletRequest currentRequest){
		return getUserInfo(currentRequest,CurrentUserInfo.class);
	}
	
	/**获取当前用户，出错**/
	public final static CurrentUserInfo  getCurrentUserInfoExcption(HttpServletRequest currentRequest)throws BizException{
		return getUserInfoExcption(currentRequest,CurrentUserInfo.class);
	}
	
	/**获取用户基本信息不会抛出错误的**/
	public final static <T extends UserSessionData> T getUserInfo(HttpServletRequest currentRequest,Class<T> userSessionData){
		T userInfoExcption = null;
		try{
			userInfoExcption = getUserInfoExcption(currentRequest,userSessionData);
		}catch (Exception e) {
			//获取用户信息不存，但不给于提示错误只负责返回确定值
		}
		return userInfoExcption;
	}
	
	/**获取用户基本信息会抛出错误的**/
	public final static <T extends UserSessionData> T getUserInfoExcption(HttpServletRequest currentRequest,Class<T> userSessionData)throws BizException{
		T model = null;//用户类型
		String userString  = (String)currentRequest.getSession().getAttribute(SessionConstant.SESSION_KEY);
    	if(StringUtils.isNotBlank(userString)){
    		try{
    			model = (T) JSON.parseObject(userString, userSessionData);
    		}catch(Exception ex){
    			log.error("用户登录信息SESSION转换错误,入参{},异常：{}",userString,ex);
    			throw BizException.SESSION_IS_OUT_TIME;
    		}
    	}else{
    		//Session用户过期
    		throw BizException.SESSION_IS_OUT_TIME;
    	}
        return model;
    }
	
	/**退出当前用户**/
	public static final boolean loginOut(HttpServletRequest currentRequest){
		try{
			if(UserInfoUtil.existUserInfo(currentRequest)){
				try{iUserAuth.removeUserAuth(UserInfoUtil.getClient(currentRequest));}catch(Exception e){log.error("退出登陆执行Runable异常",e);}
			}
			currentRequest.getSession().removeAttribute(SessionConstant.SESSION_KEY);
			return true;
		}catch(Exception ex){ex.printStackTrace();}
		return false;
	}
	
	public static final boolean loginOut(HttpSession session){
		try{
			session.removeAttribute(SessionConstant.SESSION_KEY);
			return true;
		}catch(Exception ex){ex.printStackTrace();}
		return false;
	}
	
	/**获取用户基本信息不会抛出错误的**/
	public final static boolean  setCurrentUserInfo(HttpServletRequest currentRequest,CurrentUserInfo currentUserInfo){
		return setUserInfo(currentUserInfo,currentRequest);
	}
	/**设置用户信息到全局Redis中
	 * @param userSessionData 用户基本信息
	 * @param expire 设置Session过期时间
	 **/
	public final static <T extends UserSessionData> boolean setUserInfo(T userSessionData,HttpServletRequest request){
		try{
			if(null!=userSessionData&&StringUtils.isNotBlank(userSessionData.getUserId())){
				userSessionData.setLoginTimestamp(System.currentTimeMillis());//设置当前登录的时间戳
				request.getSession().setAttribute(SessionConstant.SESSION_KEY,JSON.toJSONString(userSessionData));
		        return true;
			}
		}catch(Exception ex){
			log.error("设置用户Session失败",ex);
		}
		
		return false;
	}
	private static IUserAuth iUserAuth = null;//权限设置
	public static void setIUserAuth(IUserAuth iUserAuth) {
		if(null==UserInfoUtil.iUserAuth){
			UserInfoUtil.iUserAuth = iUserAuth;
		}
	}
	public static IUserAuth getIUserAuth(){
		return UserInfoUtil.iUserAuth;
	}
}
